package com.tinywind.admin.common.config.shiro;

import com.tinywind.admin.common.consts.SystemConst;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;


/**
 * @author liuxingyu01
 * @date 2022-03-20 12:52
 * @description 自定义SessionManager，改为从header中获取token
 * @description 为前后端分离预留的(使用时, 用来代替ShiroConfig里的DefaultWebSessionManager即可)，不分离的项目用不到
 **/
public class CustomSessionManager extends DefaultWebSessionManager {

    // 定义常量
    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";

    // 重写构造器
    public CustomSessionManager() {
        super();
        this.setDeleteInvalidSessions(true);
    }


    /**
     * 重写方法实现从请求头获取Token便于接口统一
     * 每次请求进来,Shiro会去从请求头找Authorization这个key对应的Value(Token)
     * 两种方式皆可通过会话验证  1：cookie里面带上sessionId
     * 2：在Headers里面带上Authorization，值为sessionId
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    public Serializable getSessionId(ServletRequest request, ServletResponse response) {
        // 如果请求头中有Authorization 则其值为sessionId
        String sessionId = WebUtils.toHttp(request).getHeader(SystemConst.SYSTEM_USER_TOKEN);
        if (!StringUtils.isEmpty(sessionId)) {
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
            // request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
            return sessionId;
        } else {
            // 否则按照默认规则从Cookie取sessionId
            return super.getSessionId(request, response);
        }
    }

}
